Jump to content

User Guide-Debugging Profiling and Tuning

From RidgeRun Developer Wiki

Follow us on: YouTube Twitter LinkedIn Email Share this page

Share This Page


Preferred Partner Logo 3 Partner Program Banner




The isp_app C++ example supports CSV exports, V4L2 capture, Graphviz pipeline export, and optional PVA execution statistics. The smaller isp_minimal, isp_minimal_cuda, and isp_multicamera examples also support --stats and --dump-graph, but the CSV debug exporters described here belong to isp_app. All examples use the examples/configs/params.yaml parameter structure.

Example invocation with CSV export enabled in the YAML file:

./builddir/out/bin/isp_app --image input.raw --resolution 1920x1080 \
  --parameters examples/configs/params.yaml --num-frames 26 \
  --stats --dump-graph pipeline.dot

For this example, set debug.export_debug_csv: true and debug.debug_export_frame_index: 25 in the YAML. Frame indices start at zero. The input file may contain one RAW frame, repeated for each iteration, or the requested number of concatenated frames. Use a real even image resolution and matching Bayer pattern. For capture, use --device /dev/videoN and, if needed, --format. --mask supplies a float histogram mask. The CSV export path is relative to the process working directory unless a GTM path option overrides it.

Parameter File

The following parameter file illustrates the available settings. Values are examples to calibrate for the camera. YAML keys are grouped by algorithm; the loader rejects unknown top-level keys. The debug section is optional, and the sample disables exports.

examples/configs/params.yaml

# yaml-language-server: $schema=./params.schema.yaml
# Copyright (C) 2026 RidgeRun, LLC (http://www.ridgerun.com)
# All Rights Reserved.
#
# The contents of this software are proprietary and confidential to RidgeRun,
# LLC.  No part of this program may be photocopied, reproduced or translated
# into another programming language without prior written consent of
# RidgeRun, LLC.  The user is free to modify the source code after obtaining
# a software license from RidgeRun.  All source code changes must be provided
# back to RidgeRun without any encumbrance.

# Reference parameter file for the ISP examples.
# This sample matches `params.schema.yaml` and the runtime loader used by:
# - isp_minimal
# - isp_minimal_cuda
# - isp_multicamera
# - isp_app

decompand:
  input_shift: 4
  x_pts: [0, 1098, 1885, 2501, 3062, 3602, 3914, 3975, 4095]
  y_pts: [0, 1107, 3325, 7766, 16652, 34430, 52207, 56648, 65535]

convolution:
  kernel: [1, 2, 1, 2, 4, 2, 1, 2, 1]
  shift: 4

color_correction:
  matrix: [1, 0, 0, 0, 1, 0, 0, 0, 1]
  shift: 0

black_level:
  channel00: 16
  channel01: 16
  channel10: 16
  channel11: 16

digital_gain:
  channel_gains: [1.5, 1.5, 1.5, 1.5]

white_balance:
  u_ref: [0.982, 0.789, 0.668, 0.558, 0.426]
  v_ref: [0.308, 0.382, 0.445, 0.428, 0.678]
  use_calibration: false
  manual_wb: false
  manual_wb_gains: [1.0, 1.0, 1.0]

demosaic:
  bayer_pattern: 0

histogram:
  bit_depth: 16
  use_mask: false

auto_exposure:
  kp_exposure: 40.0
  ki_exposure: 1.0
  kd_exposure: 8.0
  kp_gain: 5000000.0
  ki_gain: 10.0
  kd_gain: 500.0
  reference_mean: 120.0
  dynamic_range: 255.0
  min_exposure: 5000
  max_exposure: 20000
  min_gain: 2000000
  max_gain: 100000000
  camera_index: 0
  enable_v4l2: false

gamma_tone_mapping:
  build_lut: true
  gamma: 2.2
  lut: [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
    208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
    224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
    240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
  ]

global_tone_mapping:
  brightness: 0.18
  gtm_scale_min: 0.0001
  gtm_scale_max: 0.01
  gtm_temporal_alpha: 1.0

debug:
  export_scene_key: false
  export_debug_csv: false
  debug_export_frame_index: 0

ISP Calibration

Bayer Pattern

Set demosaic.bayer_pattern to the input mosaic: 0 BGGR, 1 RGGB, 2 GBRG, or 3 GRBG. The four black_level.channel00 through channel11 entries refer to even/odd row and column positions, not fixed colors. For BGGR, those positions are B, G, G, R respectively. Select the pattern that matches the sensor and capture format before tuning color parameters.

Decompanding

decompand.x_pts are compressed input codes; decompand.y_pts are corresponding linear 16-bit output codes. Both arrays must have equal length, contain at least two strictly increasing values, and begin at zero. The example has nine pairs, with input codes 0–4095 mapped to output codes 0–65535. Control points must fit the logical input bit depth. If the sensor already produces linear values, use an identity mapping in that same input domain.

decompand.input_shift is passed to the stage as shift_bits. It describes known-zero low alignment bits when meaningful sensor data is left-aligned in a 16-bit container. For example, a left-aligned 12-bit sample may use shift 4; a right-aligned sample uses shift 0. The low bits must actually be zero. This is not a way to discard arbitrary sensor data. The stage supports 10–16 meaningful input bits and requires bit depth plus shift to be at most 16.

Figure. decompand PWL visualization in PVA ISP Viewer.
Figure. decompand points visualization in PVA ISP Viewer.
Figure. Histogram pre decompand visualization in PVA ISP Viewer.
Figure. Histogram post decompand visualization in PVA ISP Viewer.

The PWL CSV describes the configured points. The per-pixel CSV can show whether measured output follows the curve, but its input_code_12bit column is explicitly clipped to 4095 by the exporter. Interpret that column carefully for inputs whose meaningful depth exceeds 12 bits.

Convolution and Color Correction

convolution.kernel contains nine signed coefficients in row-major order. The sample [1,2,1,2,4,2,1,2,1] is normalized by convolution.shift: 4. Convolution filters each RGB16 plane independently. color_correction.matrix is a separate 3×3 row-major matrix that mixes color channels; the sample identity matrix uses shift: 0. With --join-kernels, isp_app uses a combined Convolution + Color Correction stage and reuses these same YAML sections.

Black Level and Digital Gain

Set black_level.channel00, channel01, channel10, and channel11 from sensor optical-black measurements. The stage subtracts each offset, rescales the remaining range, applies the matching value from digital_gain.channel_gains, and clamps to 16 bits. The four gains are ordered [channel00, channel01, channel10, channel11], matching the even/even, even/odd, odd/even, and odd/odd positions in the Bayer 2×2 cell. Values must remain below 65535 so range rescaling is defined. Per-site digital gain also raises noise and can clip highlights, so inspect both dark regions and saturation after changing it.

Figure. Histogram post Black Leveling visualization in PVA ISP Viewer.

The histogram_post_black_leveling.csv export is an approximation: its exporter subtracts each configured black offset from the decompand output for histogramming, but it does not use the actual Black Level stage output or include that stage's range rescaling and per-site digital gains. Do not use this CSV alone to validate the final corrected image. The black_leveling_factors.csv and digital_gain_metrics.csv rows are computed from the loaded YAML values. The full example changes optical-black levels and gains halfway through file processing, so these two CSVs can differ from the active stage properties after that update.

White Balance

Set white_balance.manual_wb: true to use white_balance.manual_wb_gains, ordered R, G, B. With manual mode off, the pipeline estimates gains from Bayer data. With use_calibration: false, it uses channel averages. With calibration on, the five u_ref values are ln(R/G) coordinates and the five v_ref values are ln(B/G) coordinates. Choose references from representative neutral targets under the intended illuminants.

Figure. White balance histogram visualization in PVA ISP Viewer.

The white_balance_gains.csv export reports the stage's active gain triplet for the selected debug frame. Compare channel clipping and neutral areas as well as histogram shape; visually similar channel histograms alone do not prove accurate white balance.

Histogram and Auto Exposure

histogram.bit_depth sets the logical Bayer depth used for bin mapping; the PVA histogram has 256 bins. histogram.use_mask controls whether supplied mask weights are applied. The standalone histogram stage consumes one Bayer 2×2 cell per observation, and histogram.csv records its bin counts. The counts need not sum to the number of individual image pixels. Auto Exposure consumes this histogram and adjusts camera gain before exposure, within the limits in auto_exposure. Set auto_exposure.enable_v4l2: true only when the camera should receive control writes; otherwise the stage still computes and exports the controls.

Figure. Histogram visualization in PVA ISP Viewer.

When CSV debug export is enabled, auto_exposure_controls.csv records every frame's exposure, gain, measured mean, reference mean, dynamic range, settling count, and control-loop state. Use it to diagnose oscillation or limit saturation.

Demosaicing

Demosaicing reconstructs RGB16 from the balanced Bayer image. histogram_post_demosaic.csv counts one red, green, and blue value per output pixel. Compare it with the Bayer histograms as a distribution check, then inspect the image for false color, edge artifacts, and clipped channels.

Figure. Histogram post demosaicing visualization in PVA ISP Viewer.

Global Tone Mapping

global_tone_mapping.brightness sets the target scene brightness. gtm_scale_min and gtm_scale_max clamp the exposure scale and must be ordered. gtm_temporal_alpha controls white-point smoothing: 1 follows the current frame, while lower values adapt more slowly. The scene key is [mean_log2_luminance, max_luminance] and is computed by an upstream RGB stage.

Figure.GTM luminances visualization in PVA ISP Viewer.

gtm_luminances.csv compares input RGB16 luminance with tone-mapped RGB8 luminance for the selected debug frame. gtm_scene_key.csv records scene-key and white-point metrics for every frame when scene-key export is enabled. The latter is a separate CSV from the per-pixel luminance file. The input to tone mapping may have passed through Convolution and Color Correction after Demosaic.

Gamma Tone Mapping

The gamma_tone_mapping section supports a generated 256-entry LUT or an explicit table. With build_lut: true, the mapping is round(255 × (input/255)^(1/gamma)), where gamma must be finite and positive. Gamma 1 is identity; gamma greater than 1 brightens midtones under this convention. With build_lut: false, supply exactly 256 lut values from 0 to 255. The sample's identity LUT is inactive while build_lut is true.

Figure. Histogram pre Gamma Tone Mapping visualization in PVA ISP Viewer.
Figure. Post Gamma Tone Mapping histogram visualization in PVA ISP Viewer.

gamma_metrics.csv reports the YAML gamma value, even when a custom LUT is active; use the pre- and post-gamma histograms to see the actual table's effect. Histogram gaps can be normal for a quantized 8-bit LUT, so they do not necessarily indicate a processing error.

Debug Exports

Setting or option Effect
debug.export_debug_csv: true Enables scalar, histogram, and per-pixel debug CSVs in isp_app. The sample default is false.
debug.debug_export_frame_index: N Selects a zero-based frame for frame-specific outputs. With CSV export on, N must be in [0, num_frames - 1]. Default is 0.
debug.export_scene_key: true Writes GTM scene-key metrics for every processed frame, independently of the selected debug frame.
--gtm-luminances-csv PATH Overrides the per-pixel GTM luminance CSV path; default debug/gtm_luminances.csv.
--gtm-scene-key-csv PATH Overrides the scene-key CSV path; default debug/gtm_scene_key.csv.

CSV exporters expect the separate stages and their host-accessible intermediate frames. isp_app --join-kernels rejects runs when either debug.export_debug_csv or debug.export_scene_key is true. Set both false for joined mode. --stats and --dump-graph still work there.

Files and update cadence

File (default path under debug/) Contents When written
gtm_scene_key.csv frame,scene_key_avg_log2,scene_key_max_l,src_l_white_prime,dst_l_white_prime One row per frame with export_scene_key.
auto_exposure_controls.csv Exposure, gain, measured mean, reference, range, settling count, loop state. One row per frame with export_debug_csv.
histogram.csv Dedicated PVA histogram, bin,count. Selected debug frame.
histogram_pre_decompand.csv, histogram_post_decompand.csv Bayer R/G/B histograms before and after decompanding. Selected debug frame.
histogram_post_black_leveling.csv Black-offset-only approximation described above. Selected debug frame.
histogram_post_white_balance.csv, histogram_post_demosaic.csv Bayer and RGB16 channel histograms respectively. Selected debug frame.
histogram_pre_gamma.csv, histogram_post_gamma.csv RGB8 channel histograms after GTM and after Gamma. Selected debug frame.
decompand_pwl.csv PWL segment endpoints, slope, and intercept from configuration. Once at initialization with export_debug_csv.
decompand_points.csv, gtm_luminances.csv Per-pixel decompanding and GTM luminance comparisons. Selected debug frame; GTM path is configurable.
decompand_shift.csv, black_leveling_factors.csv, digital_gain_metrics.csv, white_balance_gains.csv, gamma_metrics.csv Scalar configuration and per-site gain values; see the caveats above. Selected debug frame.

Every CSV starts with a # csv_type: ... line before the column header. The seven color histogram files contain 256 rows with bin,r_count,g_count,b_count. For Bayer histograms, the red and blue totals are each about one quarter of the pixels and the two green sites together are about one half. For RGB histograms, each channel has one value per image pixel. If an external viewer does not recognize the type line, skip that first line when importing.

Profiling

--stats asks the pipeline to print per-stage PVA execution statistics. --dump-graph pipeline.dot writes the prepared pipeline as Graphviz DOT, including selected joined or separate stages. The full application also prints initialization time and an average processing interval in microseconds. These timings are useful for comparisons using the same resolution, input mode, stage graph, and profiling setting. They do not by themselves measure end-to-end camera-to-display latency; input capture, file I/O, and display are outside the reported processing interval. The single-image path also updates some stage properties halfway through its iterations, which can affect comparisons.

For repeatable tuning, save the YAML file, input image or capture conditions, resolution, pipeline mode, and profiler output with each run. Change one parameter group at a time, then compare histograms, control trajectories, scene-key values, and the final NV12 image. The images on this page are existing viewer examples; they are not outputs of the joined stages.


Cookies help us deliver our services. By using our services, you agree to our use of cookies.